package com.purchasing.system.controller;

import java.util.List;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.ArrayList;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import com.purchasing.system.model.PurchaseRequest;
import com.purchasing.system.payload.request.ApprovalRequest;
import com.purchasing.system.payload.request.PurchaseRequestDto;
import com.purchasing.system.payload.response.MessageResponse;
import com.purchasing.system.payload.response.PagedResponse;
import com.purchasing.system.security.services.UserDetailsImpl;
import com.purchasing.system.service.PurchaseRequestService;
import com.purchasing.system.exception.ResourceNotFoundException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.persistence.criteria.Predicate;
import com.purchasing.system.repository.PurchaseRequestRepository;

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@RequestMapping("/purchase-requests")
public class PurchaseRequestController {
    private static final Logger logger = LoggerFactory.getLogger(PurchaseRequestController.class);

    @Autowired
    private PurchaseRequestService purchaseRequestService;
    
    @Autowired
    private PurchaseRequestRepository purchaseRequestRepository;

    @Value("${file.upload-dir}")
    private String uploadDir;

    @PostMapping
//    @PreAuthorize("hasRole('EMPLOYEE') or hasRole('ADMIN')")
    public ResponseEntity<?> createPurchaseRequest(
            @Valid @RequestPart("purchaseRequest") PurchaseRequestDto purchaseRequestDto,
            @RequestPart(value = "attachment", required = false) MultipartFile attachment) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
        
        PurchaseRequest savedRequest = purchaseRequestService.createPurchaseRequest(purchaseRequestDto, attachment, userDetails.getId());
        
        return ResponseEntity.status(HttpStatus.CREATED).body(savedRequest);
    }

    @GetMapping
//    @PreAuthorize("hasRole('EMPLOYEE') or hasRole('ADMIN')")
    public ResponseEntity<?> getCurrentUserPurchaseRequests(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String itemName,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate) {
        
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
        
        logger.debug("获取用户采购申请列表 - 用户ID: {}, 状态: {}, 物品名称: {}, 开始日期: {}, 结束日期: {}", 
                userDetails.getId(), status, itemName, startDate, endDate);
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").descending());
        
        Page<PurchaseRequest> purchaseRequests;
        
        try {
            // 处理日期范围
            LocalDateTime startDateTime = null;
            LocalDateTime endDateTime = null;
            if (startDate != null && !startDate.isEmpty()) {
                startDateTime = LocalDate.parse(startDate).atStartOfDay();
            }
            if (endDate != null && !endDate.isEmpty()) {
                endDateTime = LocalDate.parse(endDate).plusDays(1).atStartOfDay();
            }
            
            // 根据条件筛选
            if (itemName != null && !itemName.isEmpty()) {
                // 按物品名称筛选
                purchaseRequests = purchaseRequestService.searchUserPurchaseRequestsByItemName(
                        userDetails.getId(), itemName, status, startDateTime, endDateTime, pageable);
            } else if (status != null && !status.isEmpty()) {
                // 按状态筛选
                PurchaseRequest.PurchaseStatus purchaseStatus = PurchaseRequest.PurchaseStatus.valueOf(status.toUpperCase());
                
                if (startDateTime != null && endDateTime != null) {
                    // 按状态和日期范围筛选
                    purchaseRequests = purchaseRequestService.getPurchaseRequestsByUserAndStatusAndDateRange(
                            userDetails.getId(), purchaseStatus, startDateTime, endDateTime, pageable);
                } else {
                    // 仅按状态筛选
                    purchaseRequests = purchaseRequestService.getPurchaseRequestsByUserAndStatus(
                            userDetails.getId(), purchaseStatus, pageable);
                }
            } else if (startDateTime != null && endDateTime != null) {
                // 仅按日期范围筛选
                purchaseRequests = purchaseRequestService.getPurchaseRequestsByUserAndDateRange(
                        userDetails.getId(), startDateTime, endDateTime, pageable);
            } else {
                // 获取所有
                purchaseRequests = purchaseRequestService.getPurchaseRequestsByUser(userDetails.getId(), pageable);
            }
            
            return ResponseEntity.ok(new PagedResponse<>(
                    purchaseRequests.getContent(),
                    purchaseRequests.getNumber(),
                    purchaseRequests.getSize(),
                    purchaseRequests.getTotalElements(),
                    purchaseRequests.getTotalPages(),
                    purchaseRequests.isLast()
            ));
        } catch (Exception e) {
            logger.error("获取用户采购申请列表失败 - 错误: {}", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new MessageResponse("获取采购申请列表失败: " + e.getMessage()));
        }
    }

    @GetMapping("/pending")
//    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<?> getPendingPurchaseRequests(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String itemName,
            @RequestParam(required = false) String requesterName) {
        
        Pageable pageable = PageRequest.of(page, size, Sort.by("createdAt").ascending());
        
        Page<PurchaseRequest> purchaseRequests;
        
        if (requesterName != null && !requesterName.isEmpty()) {
            // 如果提供了申请人名称，则按申请人名称筛选
            purchaseRequests = purchaseRequestService.getPendingPurchaseRequestsByRequesterName(requesterName, pageable);
        } else if (itemName != null && !itemName.isEmpty()) {
            // 如果提供了物品名称，则按物品名称筛选
            purchaseRequests = purchaseRequestService.getPendingPurchaseRequestsByItemName(itemName, pageable);
        } else {
            // 否则获取所有待审批的请求
            purchaseRequests = purchaseRequestService.getPendingPurchaseRequests(pageable);
        }
        
        return ResponseEntity.ok(new PagedResponse<>(
                purchaseRequests.getContent(),
                purchaseRequests.getNumber(),
                purchaseRequests.getSize(),
                purchaseRequests.getTotalElements(),
                purchaseRequests.getTotalPages(),
                purchaseRequests.isLast()
        ));
    }

    @GetMapping("/all")
//    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<?> getAllPurchaseRequests(
            @RequestParam(defaultValue = "0") int page,
            @RequestParam(defaultValue = "10") int size,
            @RequestParam(required = false) String status,
            @RequestParam(required = false) String itemName,
            @RequestParam(required = false) String requesterName,
            @RequestParam(required = false) String startDate,
            @RequestParam(required = false) String endDate,
            @RequestParam(required = false) Boolean approved) {
        
        logger.debug("获取所有采购申请 - 页码: {}, 每页大小: {}, 状态: {}, 物品名称: {}, 申请人: {}, 开始日期: {}, 结束日期: {}, 已审批: {}", 
                page, size, status, itemName, requesterName, startDate, endDate, approved);
        
        try {
            // 处理日期范围
            final LocalDateTime[] dateRange = new LocalDateTime[2];
            if (startDate != null && !startDate.isEmpty()) {
                dateRange[0] = LocalDate.parse(startDate).atStartOfDay();
            }
            if (endDate != null && !endDate.isEmpty()) {
                dateRange[1] = LocalDate.parse(endDate).plusDays(1).atStartOfDay();
            }
            
            // 创建分页请求
            Pageable pageable = PageRequest.of(page, size, Sort.by(Sort.Direction.DESC, "createdAt"));
            
            // 使用 Specification 进行组合查询
            Specification<PurchaseRequest> spec = (root, query, cb) -> {
                List<Predicate> predicates = new ArrayList<>();
                
                // 处理已审批条件
                if (approved != null && approved) {
                    predicates.add(cb.notEqual(root.get("status"), PurchaseRequest.PurchaseStatus.PENDING));
                }
                
                // 处理状态条件
                if (status != null && !status.isEmpty()) {
                    predicates.add(cb.equal(root.get("status"), 
                            PurchaseRequest.PurchaseStatus.valueOf(status.toUpperCase())));
                }
                
                // 处理物品名称条件
                if (itemName != null && !itemName.isEmpty()) {
                    predicates.add(cb.like(cb.lower(root.get("itemName")), 
                            "%" + itemName.toLowerCase() + "%"));
                }
                
                // 处理申请人条件
                if (requesterName != null && !requesterName.isEmpty()) {
                    String lowerRequesterName = "%" + requesterName.toLowerCase() + "%";
                    predicates.add(cb.or(
                        cb.like(cb.lower(root.get("requestUser").get("name")), lowerRequesterName),
                        cb.like(cb.lower(root.get("requestUser").get("username")), lowerRequesterName)
                    ));
                }
                
                // 处理日期范围条件
                final LocalDateTime startDateTime = dateRange[0];
                final LocalDateTime endDateTime = dateRange[1];
                if (startDateTime != null && endDateTime != null) {
                    predicates.add(cb.between(root.get("createdAt"), startDateTime, endDateTime));
                } else if (startDateTime != null) {
                    predicates.add(cb.greaterThanOrEqualTo(root.get("createdAt"), startDateTime));
                } else if (endDateTime != null) {
                    predicates.add(cb.lessThanOrEqualTo(root.get("createdAt"), endDateTime));
                }
                
                return predicates.isEmpty() ? null : cb.and(predicates.toArray(new Predicate[0]));
            };
            
            // 执行分页查询
            Page<PurchaseRequest> purchaseRequests = purchaseRequestService.findAll(spec, pageable);
            logger.debug("查询结果 - 总条数: {}, 总页数: {}, 当前页: {}", 
                    purchaseRequests.getTotalElements(), 
                    purchaseRequests.getTotalPages(), 
                    purchaseRequests.getNumber());
            
            return ResponseEntity.ok(new PagedResponse<>(
                    purchaseRequests.getContent(),
                    purchaseRequests.getNumber(),
                    purchaseRequests.getSize(),
                    purchaseRequests.getTotalElements(),
                    purchaseRequests.getTotalPages(),
                    purchaseRequests.isLast()
            ));
        } catch (Exception e) {
            logger.error("获取采购申请列表失败 - 错误: {}", e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new MessageResponse("获取采购申请列表失败: " + e.getMessage()));
        }
    }

    @GetMapping("/{id}")
//    @PreAuthorize("hasRole('EMPLOYEE') or hasRole('ADMIN')")
    public ResponseEntity<?> getPurchaseRequestById(@PathVariable Long id) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
        
        logger.debug("获取采购申请详情 - 用户ID: {}, 申请ID: {}", userDetails.getId(), id);
        
        try {
            PurchaseRequest purchaseRequest = purchaseRequestService.getPurchaseRequestById(id, userDetails.getId());
            logger.debug("采购申请详情获取成功 - ID: {}, 状态: {}", purchaseRequest.getId(), purchaseRequest.getStatus());
            return ResponseEntity.ok(purchaseRequest);
        } catch (Exception e) {
            logger.error("获取采购申请详情失败 - ID: {}, 错误: {}", id, e.getMessage());
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new MessageResponse("获取采购申请详情失败: " + e.getMessage()));
        }
    }

    @GetMapping("/{id}/attachment")
//    @PreAuthorize("hasRole('EMPLOYEE') or hasRole('ADMIN')")
    public ResponseEntity<?> downloadAttachment(@PathVariable Long id) {
        try {
            Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
            UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
            
            // 记录调试信息
            logger.debug("下载附件请求 - 用户ID: {}, 申请ID: {}", userDetails.getId(), id);
            
            // 获取采购申请信息
            PurchaseRequest purchaseRequest = purchaseRequestService.getPurchaseRequestById(id, userDetails.getId());
            
            // 检查是否有附件
            if (purchaseRequest.getAttachmentPath() == null || purchaseRequest.getAttachmentPath().isEmpty()) {
                logger.warn("下载附件失败 - 申请没有附件: {}", id);
                return ResponseEntity.notFound().build();
            }
            
            logger.debug("附件路径: {}", purchaseRequest.getAttachmentPath());
            
            // 构建文件路径
            Path filePath = Paths.get(uploadDir).resolve(purchaseRequest.getAttachmentPath()).normalize();
            logger.debug("完整文件路径: {}", filePath.toAbsolutePath());
            
            // 检查文件是否存在
            if (!Files.exists(filePath)) {
                logger.error("文件不存在: {}", filePath.toAbsolutePath());
                return ResponseEntity.status(HttpStatus.NOT_FOUND)
                        .body(new MessageResponse("文件不存在: " + purchaseRequest.getAttachmentPath()));
            }
            
            Resource resource = new UrlResource(filePath.toUri());
            
            // 检查文件是否存在
            if (!resource.exists()) {
                logger.error("无法读取文件资源: {}", filePath.toAbsolutePath());
                throw new ResourceNotFoundException("文件不存在: " + purchaseRequest.getAttachmentPath());
            }
            
            // 获取文件原始名称或使用默认名称
            String originalFilename = purchaseRequest.getAttachmentPath();
            if (originalFilename.contains("_")) {
                originalFilename = originalFilename.substring(originalFilename.indexOf("_") + 1);
            }
            
            // 设置内容类型
            String contentType = Files.probeContentType(filePath);
            if (contentType == null) {
                contentType = "application/octet-stream";
            }
            
            logger.debug("文件下载 - 类型: {}, 名称: {}", contentType, originalFilename);
            
            return ResponseEntity.ok()
                    .contentType(MediaType.parseMediaType(contentType))
                    .header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + originalFilename + "\"")
                    .body(resource);
                    
        } catch (IOException e) {
            logger.error("下载附件IO异常", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new MessageResponse("下载附件失败: " + e.getMessage()));
        } catch (Exception e) {
            logger.error("下载附件异常", e);
            return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR)
                    .body(new MessageResponse("下载附件失败: " + e.getMessage()));
        }
    }

    @PutMapping("/{id}")
//    @PreAuthorize("hasRole('EMPLOYEE') or hasRole('ADMIN')")
    public ResponseEntity<?> updatePurchaseRequest(
            @PathVariable Long id,
            @Valid @RequestPart("purchaseRequest") PurchaseRequestDto purchaseRequestDto,
            @RequestPart(value = "attachment", required = false) MultipartFile attachment) {
        
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
        
        PurchaseRequest updatedRequest = purchaseRequestService.updatePurchaseRequest(id, purchaseRequestDto, attachment, userDetails.getId());
        
        return ResponseEntity.ok(updatedRequest);
    }

    @DeleteMapping("/{id}")
//    @PreAuthorize("hasRole('EMPLOYEE') or hasRole('ADMIN')")
    public ResponseEntity<?> deletePurchaseRequest(@PathVariable Long id) {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
        
        purchaseRequestService.deletePurchaseRequest(id, userDetails.getId());
        
        return ResponseEntity.ok(new MessageResponse("Purchase request deleted successfully"));
    }

    @PostMapping("/{id}/approve")
//    @PreAuthorize("hasRole('ADMIN')")
    public ResponseEntity<?> approvePurchaseRequest(
            @PathVariable Long id,
            @Valid @RequestBody ApprovalRequest approvalRequest) {
        
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetailsImpl userDetails = (UserDetailsImpl) authentication.getPrincipal();
        
        PurchaseRequest approvedRequest = purchaseRequestService.approvePurchaseRequest(
                id, 
                approvalRequest.isApproved(), 
                approvalRequest.getComment(),
                userDetails.getId()
        );
        
        return ResponseEntity.ok(approvedRequest);
    }
} 